package top.kaoshanji.r1ch04b.speaker;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;
import org.springframework.util.ClassUtils;

/**
 * 代码清单-r1ch04b-84页b：一个BeanFactoryPostProcessor
 * @author kaoshanji
 * ^_^
 * create time 2025/5/28 18:19
 */
public class SpeakerBeanFactoryPostProcessor implements BeanFactoryPostProcessor, EnvironmentAware {

    private static final Log log = LogFactory.getLog(SpeakerBeanFactoryPostProcessor.class);

    private Environment environment;

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

        // 获取属性值
        String enable = environment.getProperty("spring.speaker.enable");
        String language = environment.getProperty("spring.speaker.language", "English");
        String clazz = "top.kaoshanji.r1ch04b.speaker." + language + "Speaker"; // 类全限定名

        // 开关为true，则注册Bean，否则结束
        if (!"true".equalsIgnoreCase(enable)) {
            return;
        }

        // 如果目标类不存在，结束处理
        if (!ClassUtils.isPresent(clazz, SpeakerBeanFactoryPostProcessor.class.getClassLoader())) {
            return;
        }

        if (beanFactory instanceof  BeanDefinitionRegistry) {
            registerBeanDefinition((BeanDefinitionRegistry) beanFactory, clazz);
        } else {
            registerBean(beanFactory, clazz);
        }

    }

    @Override
    public void setEnvironment(Environment environment) {
        this.environment = environment;
    }

    // 如果是BeanDefinitionRegistry，可以注册BeanDefinition
    private void registerBeanDefinition(BeanDefinitionRegistry beanDefinitionRegistry, String clazz) {
        GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
        beanDefinition.setBeanClassName(clazz);

        beanDefinitionRegistry.registerBeanDefinition("speaker", beanDefinition);
    }

    // 如果只能识别成ConfigurableListableBeanFactory，直接注册一个Bean实例
    private void registerBean(ConfigurableListableBeanFactory beanFactory, String clazz) {
        try {
            Speaker speaker = (Speaker) ClassUtils.forName(clazz, SpeakerBeanFactoryPostProcessor.class.getClassLoader()).getDeclaredConstructor().newInstance();

            beanFactory.registerSingleton("speaker", speaker);
        }  catch (Exception e) {
            log.error("Can not create Speaker.", e);
        }

    }

}
